package com.guli.mall.pms.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guli.common.constant.ProductAttrTypeEnum;
import com.guli.common.utils.CopyPageProperties;
import com.guli.common.utils.QuickSort;
import com.guli.mall.pms.entity.*;
import com.guli.mall.pms.entity.vo.*;
import com.guli.mall.pms.feign.ProductCategoryFeignClient;
import com.guli.mall.pms.service.*;
import com.guli.mall.serviceBase.globalException.MallException;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guli.common.utils.PageUtils;
import com.guli.common.utils.Query;

import com.guli.mall.pms.mapper.AttrGroupMapper;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupMapper, AttrGroupEntity> implements AttrGroupService {


    @Resource
    ProductCategoryFeignClient productCategoryFeignClient;

    @Resource
    AttrAttrgroupRelationService attrAttrgroupRelationService;

    @Resource
    AttrService attrService;

    @Resource
    SpuInfoService spuInfoService;

    @Resource
    ProductAttrValueService productAttrValueService;

    @Override
    public PageUtils<AttrGroupCategoryNameVo> getAttrGroupPaginationByCondition(Integer currentPage, Integer size, AttrGroupEntity attrGroupEntity) {

        Page<AttrGroupEntity> attrGroupEntityPage = new Page<>(currentPage, size);

        QueryWrapper<AttrGroupEntity> queryWrapper = new QueryWrapper<>();

        if (!ObjectUtils.isEmpty(attrGroupEntity)) {
            if (!ObjectUtils.isEmpty(attrGroupEntity.getCatelogId())) {
                queryWrapper.eq("catelog_id", attrGroupEntity.getCatelogId());
                /**
                 * 查询的是父级列表，直接返回分页数据
                 * */
                /*if (attrGroupEntity.getCatelogId() == 0) {
                    Page<AttrGroupEntity> page = this.page(attrGroupEntityPage, queryWrapper);

                    return new PageUtils<>(page);
                }*/
            }
            if (!StringUtils.isEmpty(attrGroupEntity.getAttrGroupName())) {
                queryWrapper.like("attr_group_name", attrGroupEntity.getAttrGroupName());
            }
            if (!ObjectUtils.isEmpty(attrGroupEntity.getAttrGroupId())) {
                queryWrapper.eq("attr_group_id", attrGroupEntity.getAttrGroupId());
            }
        }

        Page<AttrGroupEntity> page = this.page(attrGroupEntityPage, queryWrapper);

        //Page<AttrGroupCategoryNameVo> attrGroupCategoryNameVoPage = new Page<>();

        //BeanUtils.copyProperties(page,attrGroupCategoryNameVoPage);

        /*BeanUtils.copyProperties(page.getRecords(),attrGroupCategoryNameVoPage.getRecords());

        for (AttrGroupCategoryNameVo record : attrGroupCategoryNameVoPage.getRecords()) {

            String categoryName = productCategoryFeignClient.getCategoryName(record.getCatelogId());

            record.setCategoryName(categoryName);
        }*/
        /**
         * 因为BeanUtils直接复制带范型的Page对象会报错
         * 所以只能遍历Page 中 的Records，再拷贝
         * */
        // 新建的Page对象不含有Records对象，所以手动创建
        /*attrGroupCategoryNameVoPage.setRecords(new ArrayList<AttrGroupCategoryNameVo>((int) page.getSize()));

        // 获取源Page对象中的records
        List<AttrGroupCategoryNameVo> records = attrGroupCategoryNameVoPage.getRecords();

        // 创建临时vo为单位来拷贝资源
        AttrGroupCategoryNameVo vo = new AttrGroupCategoryNameVo();

        // 遍历源records中的元素，进行拷贝
        for (AttrGroupEntity groupEntity : page.getRecords()) {

            // 拷贝中
            BeanUtils.copyProperties(groupEntity,vo);

            // 调用category微服务，查询categoryId对应的categoryName
            String categoryName = productCategoryFeignClient.getCategoryName(groupEntity.getCatelogId());

            // 将categoryName设置进vo中
            vo.setCategoryName(categoryName);

            // 将vo添加到目标Page的records集合中
            records.add(vo);
        }

        // 拷贝源page中的total总记录数到目标page的total中
        attrGroupCategoryNameVoPage.setTotal(page.getTotal());

        // 返回
        return new PageUtils<>(attrGroupCategoryNameVoPage);*/

        /**
         * 使用自己做的工具类来拷贝Page对象
         * */
        Page<AttrGroupCategoryNameVo> voPage = CopyPageProperties.copy(page, AttrGroupCategoryNameVo.class);

        for (AttrGroupCategoryNameVo record : voPage.getRecords()) {

            if (!ObjectUtils.isEmpty(record.getCatelogId())) {
                String categoryName = productCategoryFeignClient.getCategoryName(record.getCatelogId());

                record.setCategoryName(categoryName);

            } else {
                String warn = "属性分组：" + record.getAttrGroupName() + "没有设置对应的catelogId";
                log.warn(warn);
                record.setCategoryName(warn);
            }
        }

        Comparator<AttrGroupCategoryNameVo> comparator = (c1, c2) -> {
            return c1.getSort() - c2.getSort();
        };
        QuickSort.sort(voPage.getRecords(), comparator);

        return new PageUtils<>(voPage);
    }


    @Override
    public List<AttrGroupAndAttrVo> getAttrGroupAndItsAttrList(Long catelogId, AttrEntity attrEntity) {

        QueryWrapper<AttrGroupEntity> attrGroupEntityQueryWrapper = new QueryWrapper<>();

        attrGroupEntityQueryWrapper.eq("catelog_id", catelogId);

        // 查询到catelogId下的所有属性分组attrGroup
        List<AttrGroupEntity> attrGroupList = this.list(attrGroupEntityQueryWrapper);

        if (CollectionUtils.isEmpty(attrGroupList)) {
            throw new MallException("catelog_id = " + catelogId + "，该目录下没有对应的属性分组");
        }

        QuickSort.sort(attrGroupList, (group1, group2) -> {
            return group1.getSort() - group2.getSort();
        });

        List<AttrGroupAndAttrVo> attrGroupAndAttrVos = new ArrayList<>();

        for (AttrGroupEntity attrGroup : attrGroupList) {

            //通过attrGroupId在attr-group-relation中查询到与之有关联的attrId
            QueryWrapper<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntityQueryWrapper = new QueryWrapper<>();

            attrAttrgroupRelationEntityQueryWrapper.eq("attr_group_id", attrGroup.getAttrGroupId());

            List<AttrAttrgroupRelationEntity> relationEntities = attrAttrgroupRelationService.list(attrAttrgroupRelationEntityQueryWrapper);

            /**
             * 拷贝attrGroup的属性放到新的vo中
             * 要放在continue之前
             * */
            AttrGroupAndAttrVo attrGroupAndAttrVo = new AttrGroupAndAttrVo();

            BeanUtils.copyProperties(attrGroup, attrGroupAndAttrVo);

            //放入list中
            attrGroupAndAttrVos.add(attrGroupAndAttrVo);

            if (CollectionUtils.isEmpty(relationEntities)) {
                // 该attr-group-id 属性分组下没有对应的属性
                continue;
            }

            QuickSort.sort(relationEntities, (relation1, relation2) -> {
                return relation1.getAttrSort() - relation2.getAttrSort();
            });

            // 从relationList中抽取出所有的attrId，并作为一个list
            List<Long> attrIdList = relationEntities.stream().map(relation -> {
                return relation.getAttrId();
            }).collect(Collectors.toList());


            // 根据 attrIdList 和其他条件，查询到该attr-group下所有attr
            List<AttrEntity> attrEntities = attrService.listByIdsAndOtherCondition(attrIdList, attrEntity);

            //添加封装productAttrValueEntity的部分属性
            List<AttrForBindingValueVo> attrForBindingValueVoList = attrEntities.stream().map(attr -> {


                AttrForBindingValueVo attrForBindingValueVo = new AttrForBindingValueVo();

                BeanUtils.copyProperties(attr, attrForBindingValueVo);

                //设置两个默认值
                attrForBindingValueVo.setAttrSort(0);

                attrForBindingValueVo.setQuickShow(false);

                return attrForBindingValueVo;

            }).collect(Collectors.toList());

            // 将attrGroupId下的attr放入attrGroupVo中
            attrGroupAndAttrVo.setAttrList(attrForBindingValueVoList);

        }

        return attrGroupAndAttrVos;
    }

    @Override
    public List<AttrGroupAndAttrVo> querySpuInfoAttrValueAndFillIntoAttrGroup(Long spuInfoId) {

        // 查询到spu实体
        SpuInfoEntity spuInfo = spuInfoService.getById(spuInfoId);

        // 查询spu所属的 categoryId 查询出 attrGroup
        List<AttrGroupEntity> attrGroupList = this.getAttrGroupByCategoryId(spuInfo.getCatalogId());

        // 创建一个用于返回结果的list
        ArrayList<AttrGroupAndAttrVo> attrGroupAndAttrVos = new ArrayList<>(attrGroupList.size());

        // 遍历attrGroup
        for (AttrGroupEntity attrGroup : attrGroupList) {

            Long attrGroupId = attrGroup.getAttrGroupId();

            // 拷贝对象并放到 list中
            AttrGroupAndAttrVo attrGroupAndAttrVo = new AttrGroupAndAttrVo();

            BeanUtils.copyProperties(attrGroup, attrGroupAndAttrVo);

            attrGroupAndAttrVos.add(attrGroupAndAttrVo);

            // 从 attr-attr-group-relation 中获取到 attr-group-id 对应的 attrIdList
            List<Long> attrIdList = attrAttrgroupRelationService.getAttrIdListByAttrGroupIdList(attrGroupId);

            // 从 attr 表中获取到 attrIdList 对应的实体类
            List<AttrEntity> attrEntities = attrService.getBaseMapper().selectBatchIds(attrIdList);

            /**
             * AttrForBindingValueAndDisplayValueMultipleVo 和 AttrForBindingValueAndDisplayValueSingleVo 都继承了 AttrForBindingValueVo类
             *
             * */
            List<AttrForBindingValueVo> attrForBindingValueVos = attrEntities.stream().map(attr -> {

                ProductAttrValueEntity valueEntity = productAttrValueService.getAttrValueByAttrIdAndSpuId(attr.getAttrId(), spuInfo.getId());

                if(ObjectUtils.isEmpty(valueEntity)){

                    AttrForBindingValueVo attrForBindingValueVo = new AttrForBindingValueVo();

                    BeanUtils.copyProperties(attr,attrForBindingValueVo);

                    return attrForBindingValueVo;
                }

                // 实际可以选择的数组
                String[] valueSelectArray = attr.getValueSelect().split(",");

                // 可以多选
                if (attr.isSelectMultiple()) {

                    // 当前已经选择了的数组
                    String[] attrValueArray = valueEntity.getAttrValue().split(",");


                    List<Integer> selectedValueIndexArray = IntStream.range(0, valueSelectArray.length)
                            .mapToObj(i -> {

                                for (int j = 0; j < attrValueArray.length; j++) {
                                    if (valueSelectArray[i].equals(attrValueArray[j])) {
                                        return i;
                                    }
                                }
                                return null;
                            })
                            .filter(i -> {
                                return i != null;
                            }).collect(Collectors.toList());

                    /*for (int i = 0; i < valueSelectArray.length; i++) {

                        for (int j = 0; j < attrValueArray.length; j++) {
                            if (valueSelectArray[i].equals(attrValueArray[j])) {
                                return i;
                            }
                        }
                    }*/
                    AttrForBindingValueAndDisplayValueMultipleVo attrForBindingValueAndDisplayValueMultipleVo = new AttrForBindingValueAndDisplayValueMultipleVo();

                    BeanUtils.copyProperties(attr, attrForBindingValueAndDisplayValueMultipleVo);

                    attrForBindingValueAndDisplayValueMultipleVo.setId(valueEntity.getId());

                    attrForBindingValueAndDisplayValueMultipleVo.setQuickShow(valueEntity.getQuickShow());

                    attrForBindingValueAndDisplayValueMultipleVo.setAttrSort(valueEntity.getAttrSort());

                    attrForBindingValueAndDisplayValueMultipleVo.setSelectedValueIndexArray(selectedValueIndexArray);

                    return attrForBindingValueAndDisplayValueMultipleVo;
                } else {
                    // 只能单选
                    AttrForBindingValueAndDisplayValueSingleVo attrForBindingValueAndDisplayValueSingleVo = new AttrForBindingValueAndDisplayValueSingleVo();

                    BeanUtils.copyProperties(attr,attrForBindingValueAndDisplayValueSingleVo);

                    for (int i = 0; i < valueSelectArray.length; i++) {
                        if (valueSelectArray[i].equals(valueEntity.getAttrValue())) {
                            attrForBindingValueAndDisplayValueSingleVo.setSelectedValueIndexArray(i);
                        }
                    }

                    attrForBindingValueAndDisplayValueSingleVo.setId(valueEntity.getId());

                    attrForBindingValueAndDisplayValueSingleVo.setQuickShow(valueEntity.getQuickShow());

                    attrForBindingValueAndDisplayValueSingleVo.setAttrSort(valueEntity.getAttrSort());

                    return attrForBindingValueAndDisplayValueSingleVo;
                }

            }).filter(attrForBinding->{
                return  !ObjectUtils.isEmpty(attrForBinding);
            }).collect(Collectors.toList());

            attrGroupAndAttrVo.setAttrList(attrForBindingValueVos);

        }

        return attrGroupAndAttrVos;
    }

    @Override
    public List<AttrGroupEntity> getAttrGroupByCategoryId(Long categoryId) {

        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();

        wrapper.eq("catelog_id", categoryId);

        return this.list(wrapper);
    }

}